package com.derschmale.wick3d.cameras
{
	import com.derschmale.wick3d.core.data.GeometryData;
	import com.derschmale.wick3d.core.math.Transformation3D;
	import com.derschmale.wick3d.core.math.Vector3D;
	import com.derschmale.wick3d.core.objects.HierarchicObject3D;
	import com.derschmale.wick3d.core.objects.SpatialObject3D;
	import com.derschmale.wick3d.projections.IProjection;

	public class ChaseCamera3D extends Camera3D
	{
		private var _height : Number;
		
		// target position in target's object space
		private var _targetOS : Vector3D;
		
		public function ChaseCamera3D(target : SpatialObject3D, distance : Number = 100, height : Number = 50, fov:Number=Math.PI, projection:IProjection=null)
		{
			this.target = target;
			_height = height;
			_targetOS = new Vector3D(0, height, -distance, 1);
		}
		
		public function get height() : Number
		{
			return _targetOS.y;
		}
		
		public function set height(value : Number) : void
		{
			_targetOS.y = value;
		}
		
		public function get distance() : Number
		{
			return -_targetOS.z;
		}
		
		public function set distance(value : Number) : void
		{
			_targetOS.z = -value;
		}
		
		override public function transformToViewCoords(geometryData:GeometryData, camera:Camera3D, parentTransform:Transformation3D=null, recursive:Boolean=true):void
		{
			var targetPos : Vector3D = targetPosition;
			x = (x*9+targetPos.x)*0.1;
			y = (y*9+targetPos.y)*0.1;
			z = (z*9+targetPos.z)*0.1;
			
			super.transformToViewCoords(geometryData, camera, parentTransform, recursive);
		}
		
		private function get targetPosition() : Vector3D
		{
			 var worldPos : Vector3D;
			 
			 if (target is HierarchicObject3D) {
			 	worldPos = _targetOS.clone();
			 	worldPos.x /= target.scaleX;
			 	worldPos.y /= target.scaleY;
			 	worldPos.z /= target.scaleZ;
			 	worldPos = HierarchicObject3D(target).localToGlobal(worldPos);
			 }
			 else {
			 	worldPos = target.position.add(_targetOS);
			 }
			 
			 return worldPos;
		}
	}
}